home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Applications / Fractal Generator / Documentation / IFS-Manual.txt < prev    next >
Text File  |  1993-06-07  |  38KB  |  1,063 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.                                   FRACTAL LAB KIT
  15.  
  16.                                 IFS mappings module
  17.  
  18.  
  19.                                  Ronald T. Kneusel
  20.                                     May 25, 1993
  21.                                     version 1.0
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40. Table of Contents
  41.  
  42.  
  43.  
  44. I.  Introduction
  45.     What is this all about?.................................    3
  46.     Fractals and IFS (Iterated Function System).............    5
  47.     Getting started.........................................    10
  48.     
  49.  
  50. II. Tutorial
  51.     A sample session........................................    11
  52.     Using preset fractal maps...............................    12
  53.     Using basic commands....................................    12
  54.     Using the FindMap command,  an example..................    15
  55.  
  56.  
  57. III. Advanced features
  58.     A very brief introduction to programming in Forth.......    16
  59.     An example :  the  Sierpinski Triangle..................    19
  60.     Basic Forth words.......................................    21
  61.  
  62.  
  63. IV. Reference
  64.     
  65.     Commands................................................    22
  66.     Primitive words.........................................    25
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. Introduction
  82.  
  83.    What is this all about?
  84.  
  85.     The fractal lab kit is a command driven system for generating and 
  86. investigating fractal images.  It is written using Chris Heilman's Pocket 
  87. Forth  , a small Forth interpreter for the Macintosh.  Pocket Forth  is 
  88. available via anonymous FTP from archive.umich.edu in the directory 
  89. /mac/development/languages/.
  90.     The kit consists of a set of Forth words that allow the user to easily 
  91. create fractals based on IFS mappings.  Because of it's small size and 
  92. generality,  it should run on virtually all Macintosh computers.  By 
  93. entering simple commands the user can define maps, draw the resultant 
  94. fractals in a variety of colors, show the orientation of the mappings, 
  95. measure positions within the image, and zoom in to view details.  Fractals 
  96. using up to 12 maps can be generated. 
  97.  
  98.     Why not create a standard Macintosh application for all of this?
  99.  
  100.     I used Forth for two reasons.  First, I am still learning the language 
  101. and thought that this would be a good project towards that end.  
  102. Secondly,  I have used several fractal programs in the past and while they 
  103. are excellent at what they do, they are rigid and inflexible.  Creating a 
  104. system like this in Forth seemed ideal.  Forth is fast and highly 
  105. interactive.  It is also small and very easily extended.  Not only does 
  106. the user have all the fractal commands, but they also have all of Forth 
  107. still at their disposal.  A little programming can quickly extend the 
  108. existing capabilities.  Pocket Forth  was my choice for several reasons, 
  109. primarily, it is free and can be freely distributed, as well as supporting 
  110. floating point numbers to make life easier.
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.     Fractal Lab Kit is freeware,  if you use it and have any suggestions or 
  122. comments please let me know at the addresses below.  I have plans for 
  123. additional 'modules' for investigating Mandelbrot and Julia sets, biomorph 
  124. images, and chaos in one and two dimensions.  Your feedback will encourage 
  125. me to continue.  Even if you have no specific comment, let me know where 
  126. you are so I can follow the program.  I prefer postcards, but email is 
  127. good too.
  128.  
  129. Ron Kneusel
  130. 507 S. 92nd St.
  131. Milwaukee, WI  53214  
  132. USA
  133.  
  134. kneusel@msupa.pa.msu.edu 
  135. or 
  136. rtk@herman.gem.valpo.edu
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.    Fractals and IFS: an overview
  161.  
  162.     A fractal is a geometric object with a non-integer dimension.  We are 
  163. used to thinking in terms of Euclidean geometry, that is, in terms of 
  164. points, lines, areas (surfaces), and volumes (solids).  Fractals do not 
  165. easily fit in such a framework and are difficult to comprehend (at least 
  166. for me).  Common geometrical objects have integer dimensions:
  167.  
  168.         Object        Dimension
  169.         ------        ----------
  170.         point            0        (no length or width or depth)
  171.         line            1        (length only, no width or depth)
  172.         plane            2        (length and width)
  173.         solid            3        (length, width and depth)
  174.  
  175. but fractals have non-integer dimensions, like 0.63... etc.   How can this 
  176. be you say? Let's look at the simplest fractal of them all: the Cantor set.
  177.  
  178. To create the Cantor set imagine a line of length 1.  Now, remove the 
  179. middle third of that line.  Remove the middle third of the two remaining 
  180. lines.  Continue removing the middle third an infinite number of times.  
  181. When you are finished the object you will be left with is a fractal with a 
  182. dimension that is not 0 (it's not a point) but is less than 1 (a line from 
  183. 0 to 1 would contain all points, clearly a cantor set does not) and it can 
  184. be shown that the final dimension is ln2/ln3 = 0.6309297536.....
  185.  
  186. •••••• Begin Aside:    Derivation of the Cantor Set dimension
  187.  
  188.     One possible definition of dimension, the self-similar dimension, is the 
  189. ratio of the natural log of the number of intervals N (in 1-d) of length ß 
  190. needed to completely cover the set to the natural log of the reciprocal of 
  191. ß, taken in the limit that ß-->0.  In the case of the Cantor set ß=(1/3)^n 
  192. where n is the "level" of the set. (Check: the second level has two 
  193. sections of length 1/3 while the next level has four sections of length 
  194. 1/9 = (1/3)^2)  So the condition ß-->0 becomes n-->∞ .  Also, for the 
  195. Cantor set the number of intervals to cover the set at the level n is 
  196. N=2^n .  (Check:  at the second level there are 2^1 = 2 intervals, at the 
  197. third level there are 2^2=4 intervals and so on.)  So we write:
  198.  
  199.          lim                                 lim
  200. D  =   n-->∞  ln N / ln (1/ß) =  n-->∞  ln (2^n) / ln ( 1/(1/3)^n)
  201.  
  202.          lim
  203. D  =   n-->∞  n ln 2 / n ln 3   =   ln2 / ln3  =  0.6309297536..... 
  204.  
  205. •••••• End Aside
  206.  
  207. The Cantor set, like other purely mathematical fractals, is completely 
  208. self-similar.  That is, it looks identical on different scales (actually 
  209. it is independent of scale).  Take a piece of paper (you do have scrap 
  210. paper near the computer; don't you?) and draw the first few lines of the 
  211. Cantor set, one below the other:
  212.  
  213. -------------------------
  214. --------        ---------
  215. ---  ---        ---   ---
  216. etc.
  217.  
  218. (Yours will undoubtedly look better than mine)
  219.  
  220. If you look at what you have just drawn you will notice that if you 
  221. magnify a lower level it will look like one above it,  the entire set is 
  222. made up of an infinite number of copies of itself.  (Infinity shows up 
  223. frequently when talking about fractals)  As this is a one dimensional 
  224. fractal it is not terribly interesting; the program draws two dimensional 
  225. fractals where life is a little less boring.  
  226.  
  227. They are definitely odd, but fractals do turn up in many places in nature, 
  228. the nautilus shell (see the SPIRAL), your lungs and circulatory system 
  229. (see the TREE), etc.  Some people even think that the distribution of 
  230. matter in the universe is a fractal.
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237. What about fractals and chaos?
  238.  
  239.     Fractals are often mentioned in connection with chaotic behavior of 
  240. dynamical systems.  The link comes from the fact that the final attractor 
  241. (a strange attractor) of a dissipative dynamical system is a fractal 
  242. object.  If you want to talk more about this, contact me at the above 
  243. address.
  244.  
  245.  
  246.  
  247. What is IFS?
  248.  
  249.     IFS (Iterated Function System) is the means by which the program 
  250. generates images.  It was developed by Michael Barnsley.  IFS involves 
  251. defining a number of maps that in some way determine what the final 
  252. product will look like (more on that later).  An initial point is chosen 
  253. (the origin is nice) and iterated (i.e. put it in - get something out - 
  254. put that something back in, etc.) .  These are maps in the mathematical 
  255. sense - roughly, a way of transforming a collection of points into another 
  256. space or back into its own space as is the case here.  The map used for 
  257. each iteration is chosen at random based on the assigned probability, the 
  258. higher the probability the more likely that map is chosen.  After each 
  259. iteration the resulting point is plotted.  As this process is continued 
  260. the fractal image is built.  Changing the probability of a map can 
  261. dramatically affect the resulting image, so it might take a bit to get the 
  262. picture "just right".  It should be noted that the IFS algorithm is the 
  263. heart of new data compression techniques that can achieve compression 
  264. ratios of up to 30:1.
  265.  
  266.     In mathematical terms, a 2 dimensional map can be most easily represented 
  267. in matrix form.  A matrix is similar to the two dimensional arrays used in 
  268. many programming languages.  If we have a starting point (x,y) and we want 
  269. to find the transformed coordinates, (x',y'), we can write the 
  270. transformation in this way:
  271.  
  272.       |x'|     |a  b| |x|    |e|
  273.       |y'|  =  |c  d| |y|  + |f|
  274.  
  275. This is equivalent to writing two equations:
  276.  
  277.        x'   =   a*x  +   b*y    +  e
  278.        y'   =   c*x  +   d*y    +  f
  279.  
  280. The 2x2 matrix controls the reorientation of the initial coordinate system 
  281. while the vector (e f) is an offset to a new origin point for the map. 
  282.  
  283. Finding the "magic" numbers for an IFS transformation
  284.  
  285.  
  286.     By way of example, I will show how to find the matrix values that 
  287. generate what has become known as the Mandelbrot Dragon.  While the dragon 
  288. is usually generated according to a prescription (like the Cantor set 
  289. above) it can also be found using two mappings (i.e. two matrices).  
  290.     Recalling that a fractal is made up of an infinite number of copies of 
  291. itself, we need only specify the "first" copy and the IFS algorithm will 
  292. fill in the rest.  Therefore, imagine a square from 0 to 1, this is the 
  293. starting point as it were.  We must transform the points from this square 
  294. into a different square (or squares), where the number of transformations 
  295. equals the number of "parts" that the fractal is made up of.  The dragon 
  296. is made up of two parts: a contracted 45 degree rotation of the coordinate 
  297. axes and a contracted -45 degree rotation (with a flip).  Perhaps the best 
  298. way to imagine this is to picture an arrow:  ____________\_    from 0 to 
  299. 1, the head of the arrow is only a half head so we can see if there is a 
  300. flip as well as a rotation and translation.  After some thought we realize 
  301. that we need something like the following to generate the dragon:  Again 
  302. take a piece of paper and draw a 2 inch arrow as above, the head of the 
  303. arrow is on the right and the barb is pointing north.  Now, draw another 
  304. arrow from the left edge of the first going at a 45 degree angle until it 
  305. intersects an imaginary line running north to south that passes through 
  306. the midpoint of the first line.   Draw the barb of this arrow on the left 
  307. side of the right endpoint of this line.  Finally, complete the triangle 
  308. and draw the barb of this arrow on the left side and touching the head of 
  309. the second arrow.  When you are finished you will have something like 
  310. this: 
  311.   
  312.  
  313. ( see the MacPaint file 'Dragon Picture' )
  314.  
  315.  
  316.  
  317.  
  318. where the directions of the arrow heads are crudely indicated.  Finally, 
  319. complete each of the three squares determined by the arrows as one edge.  
  320.  
  321.     Now comes the fun part,  how do we change the drawing into the numbers 
  322. for the maps?  To find the maps we need to solve, for each map, two 
  323. systems of three linear equations since there are six numbers to find.  To 
  324. write the six equations we must know where at least three points of the 
  325. original square (the one from 0 to 1) map to in the new maps.  This is 
  326. where the arrow head directions become important.  The arrow determines 
  327. two points for us, the head and the tail, while the last point can be 
  328. either of the two corners of the original square and where they map to in 
  329. the final square.  So, to this end, label the tail and head of the first 
  330. arrow drawn (a1,a2) and (b1,b2) respectively, and label the corner of the 
  331. square above (a1,a2) as (c1,c2).  These are the original three points, now 
  332. label the corresponding points in the second square (the one at a positive 
  333. 45 degree angle to the first) as (A1,A2) for the tail (in this case they 
  334. are the same point) and (B1,B2) for the head.  Label the farthest left 
  335. corner of the square (C1,C2).  
  336.  
  337. Once this is done, we can write the following six equations to determine 
  338. the first map:
  339.  
  340. a1*a + a2*b + e  =  A1
  341. b1*a + b2*b + e  =  B1
  342. c1*a + c2*b + e  =  C1
  343.  
  344. and
  345.  
  346. a1*c + a2*d + f  =  A2
  347. b1*c + b2*d + f  =  B2
  348. c1*c + c2*d + f  =  C2
  349.  
  350. In order to get actual numbers, we need to impose a coordinate system.  
  351. Draw an x and y axis where the first arrow goes from 0 to 1 on the x axis 
  352. and left edge of the first square goes from 0 to 1 on the y axis.  In this 
  353. coordinate system, (a1,a2)=(0,0); (b1,b2)=(1,0); (c1,c2)=(0,1) and the 
  354. points for the first map are (A1,A2)=(0,0); (B1,B2)=(0.5,0.5); 
  355. (C1,C2)=      (-0.5,0.5).  
  356.     The values for the matrix and vector are found by solving the two 
  357. systems.  Cramer's Rule allows the solutions to be written as:
  358.  
  359.  
  360.  
  361.     |A1 a2 1|               |a1 A1 1|                 |a1 a2 A1|
  362.     |B1 b2 1|               |b1 B1 1|                 |b1 b2 B1|
  363.     |C1 c2 1|               |c1 C1 1|                 |c1 c2 C1|
  364. a = ---------          b =  ---------             e = ----------
  365.     |a1 a2 1|               |a1 a2 1|                 |a1 a2 1 |
  366.     |b1 b2 1|               |b1 b2 1|                 |b1 b2 1 |
  367.     |c1 c2 1|               |c1 c2 1|                 |c1 c2 1 |
  368.  
  369.  
  370. Where the vertical lines represent the determinant (not the matrix as I 
  371. have been using them for previously) and with a corresponding set for the 
  372. c, d, and f values.  With these we find that the first transformation is:
  373.  
  374. |x'|      |0.5 -0.5| |x|    |0|
  375. |y'|  =   |0.5  0.5| |y|  + |0|
  376.  
  377. and applying the above to the second map gives:
  378.  
  379. |x'|     |-0.5 -0.5| |x|   |1|
  380. |y'|  =  | 0.5 -0.5| |y| + |0|
  381.  
  382. (I will leave the actual solution as an exercise.....)
  383.  
  384. The last thing to consider is what sort of probability we want to assign 
  385. to each of these maps.  Since there is no reason to favor one map to 
  386. another we can in this case get away with a probability of 0.5 for each 
  387. (remember, probabilities should add to 1).  This is not always the case, 
  388. though.
  389.     There are many good books on fractals and chaos at all levels, check the 
  390. local book store or library.  The book "Chaos: The Making of a New 
  391. Science" by John Gleick is a good place to start, though it is lean on the 
  392. technical aspects.
  393.  
  394. Getting Started
  395.     The IFS module includes a few different files.  Double click the file 
  396. Fractal Lab Kit  to get things going.  It contains the core IFS words.  
  397. The file IFS-Maps contains about a dozen predefined fractal maps that will 
  398. illustrate much of the versatility that can be obtained. (Thanks to Dr. 
  399. Dale Snider, UW-Milwaukee Dept. of Physics, for the maps).   Use Open 
  400. under the File menu to load the maps.  Enter the command PRESET to choose 
  401. a map.
  402.     The commands you enter are really just Forth words.  In fact, you are 
  403. really using Pocket Forth  with the IFS words already defined, however, 
  404. you need not be familiar with Forth to use the program.
  405.  
  406. Tutorial
  407.  
  408.  
  409.    A Sample Session
  410.  
  411.     In this sample session and what follows, things the user types are 
  412. indicated in bold while the computer's response is in plain text.
  413.  
  414. <after double-clicking the Fractal Lab Kit  icon...>
  415.   ok _open <return>
  416. <choose the IFS-Maps file from the standard Mac open dialog>
  417.   ok _fern green color on outlines draw
  418. <program loads the maps for the fern, draws the outlines of the maps, 
  419. waits for a keypress, and draws the fern in green until the user presses a 
  420. key>
  421.  ok _mouse
  422. <program shows the true coordinates of the mouse pointer until the user 
  423. presses a key>
  424.  ok _settings
  425.  Current plot origin ( 0.00000 , 0.00000 )
  426.  Current screen origin ( 100 , 330 )
  427.  Current x & y scale is 1.0000 : 1.0000
  428.  Axes are currently OFF
  429.  Draw Outlines is currently ON
  430.  Current number of maps = 5
  431.  ok _off outlines 0.178 0.034 origin .25 range cdraw
  432. <program zooms in to the second leaflet and generates a magnified image 
  433. using a different color for each map until a keypress>
  434.  ok _bye
  435. <program exits>
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  Using the Preset Fractal Maps
  447.  
  448.  
  449.     The file IFS-Maps  contains code for about a dozen fractals.  Use the 
  450. word open or Open from the File menu to load the file.  The command preset 
  451. will bring a menu allowing the user to choose a particular fractal.  Once 
  452. the maps are loaded, the fractal can be generated by typing draw.  All of 
  453. the preset fractals should appear well centered on the screen, though to 
  454. see all of the tree enter 250 330 screen draw to adjust the screen origin 
  455. so that the entire image will fit, then enter reset to restore the default 
  456. settings.
  457.     At present, there is no way to store or print the images other than the 
  458. open-apple-shift-3 command.  They can then be loaded into TeachText and 
  459. from there to any paint type program.
  460.  
  461.  
  462.   Basic Commands
  463.  
  464.  
  465.     A list of the basic, and most interactive, commands are presented along 
  466. with an example of their use.  These are the minimum commands necessary to 
  467. use the program:
  468.  
  469. draw
  470.     Draw a fractal based on the current maps.  Press a key to stop.
  471.     E.g.    green color fern draw
  472.  
  473. cdraw
  474.     Except for plotting each map in a different color, it is the same as
  475.     draw.
  476.     E.g.    spiral cdraw
  477.  
  478. <n> edit
  479.     Edit the n-th map.  Enter a new value or press return to leave the
  480.     existing value as is.
  481.     E.g.    2 edit
  482.       a = 0.5        ?-0.5    (new value)
  483.       b = -0.5        ?<return>   etc.
  484.  
  485. zero-maps
  486.     Erase all twelve maps.
  487.     E.g.    zero-maps
  488.  
  489. <color.name> color
  490.     Set the current drawing color to the color named.  Valid colors are
  491.     black, wite, red, green, blue, yellow, cyan, magenta
  492.     E.g.    magenta color
  493.  
  494. <n> maps
  495.     Set the number of maps to use to <n>.
  496.     E.g.    4 maps
  497.  
  498. <x> <y> origin
  499.     Set the origin to (x,y).  X and Y are floating point numbers.
  500.     E.g.    -0.354 .789 origin
  501.  
  502. <u> <v> screen
  503.     Set the screen origin to (u,v) (pixels).
  504.     E.g.    120 220 screen
  505.  
  506. <r> range
  507.     Set the range to <r> (floating point).  The viewing window is a
  508.     square with the lower left corner as the origin and side length
  509.     as range.
  510.     E.g.    0.5 range
  511.  
  512. <x> <y> scale
  513.     Set the x-axis and y-axis scales to the floating point values given.
  514.     The default scale is 1.0 for a full screen image.  Changing the scale
  515.     to a value less than one shrinks the image, greater than one expands
  516.     the image.
  517.     E.g.    2.0 2.0 scale
  518.  
  519. mouse
  520.     When issued, mouse will translate the position of the pointer into
  521.     an x,y coordinate allowing the user to 'see' where certain parts of 
  522.     the image are.  Clicking the mouse button between two points will
  523.     measure the distance between them.  Press a key to exit.
  524.  
  525. on|off axes
  526.     Turn the coordinate axes (really a mark on the origin) ON or OFF.
  527.     E.g.    off axes
  528.  
  529. on|off outlines
  530.     Set showing the map outlines on or off, press a key to continue
  531.     after viewing the outlines.
  532.     E.g.    on outlines
  533.  
  534. settings
  535.     Show a list of the current origin, screen origin, range, scale, number
  536.     of maps and whether the axes and outlines are on or off.
  537.     E.g.    settings
  538.  
  539. findmap
  540.     Allows the user to enter three initial coordinates and three image
  541.     coordinates and calculates the map for those values.
  542.     E.g.    findmap
  543.  
  544. make
  545.     Puts the most recent values from findmap on the stack in order
  546.     for set.  The user needs to add the probability and map number
  547.     before calling set.
  548.     E.g.    make .333 1 set
  549.  
  550. <a> <b> <c> <d> <e> <f> <p> <n> set
  551.     Sets the parameters for a map.  The letters a-f correspond to the 
  552.     values for the matrix and offset vector, <p> is the probability for
  553.     the map and <n> is the map number.  All values except <n> are to
  554.     be floating point numbers.
  555.     E.g.    0.5 -0.5 0.5 0.5 0.0 0.0 0.5 1 set
  556.  
  557. <m1> <m2> copy
  558.     Copy map number <m1> to <m2> without disturbing <m1>.
  559.     E.g.    2 5 copy
  560.  
  561. <m> delete
  562.     Delete map number <m> and move any other maps up in memory.
  563.     E.g.    3 delete
  564. <m> insert
  565.     Insert a blank map before map <m>.
  566.     E.g.    1 insert
  567.  
  568. cls
  569.     Clear the window.
  570.     E.g.    cls
  571.  
  572. bye
  573.     Exit Fractal Lab Kit.
  574.     E.g.    bye
  575.  
  576.  
  577.  
  578.     Using the FindMap command  :  an example
  579.  
  580.     The FindMap command is perhaps the most useful command.  It allows the 
  581. user to find the parameters for a map by entering the coordinates and 
  582. where they map to.  This example will use the FindMap command to calculate 
  583. the maps to find the Mandelbrot dragon which was introduced above.
  584.  
  585.     With in the program enter findmap.  You will see be asked to enter the 
  586. coordinates of three points from the original map.  The origin, the lower 
  587. right and upper left corners of the initial box (remember, it goes from 
  588. 0..1 in both x and y) make good starting places.  Therefore, enter 0 for 
  589. x1 and 0 for y1, (1,0) for (x2,y2), and (0,1) for (x3,y3).  You do not 
  590. need to enter a decimal point with each number in this case, you can also 
  591. press return to use the previously set value if desired (though it is not 
  592. shown).  For the image points, enter (x1',y1') as (0,0), (x2',y2') as 
  593. (0.5,0.5) and (x3',y3') as (-0.5,0.5).  The program will calculate the 
  594. appropriate map and display its values.  At the prompt, enter make 0.5 1 
  595. set to make this newly calculated map the first map.  Enter findmap again 
  596. and press return for each of the original points since we will use the 
  597. same ones as before.  For the image points enter (x1',y1') as (1,0), 
  598. (x2',y2') as (0.5,0.5) and (x3',y3') as (0.5,-0.5).  Then enter make 0.5 2 
  599. set to fix this as the second map.  Lastly, enter 2 maps 120 220 screen 
  600. cdraw to use two maps, adjust the screen origin so the image will fit, and 
  601. draw using color.
  602.  
  603.  
  604.  
  605.  
  606. Advanced Features
  607.  
  608.  
  609.    A very (very) brief introduction to programming in Forth
  610.  
  611.  
  612.     Forth is an interpreted, stack based programming language known for its 
  613. speed and extensibility.  This is not an attempt to completely teach Forth 
  614. so much as to teach a little about Forth so that the user who is 
  615. unfamiliar with Forth can make some use of the language.
  616.     Forth is a stack based language, data is manipulated using a stack that 
  617. works in a way very similar to the lunch trays in a cafeteria.  The last 
  618. tray in the stack is the first one out.  Because of this, all mathematical 
  619. operations are in postfix format, i.e., instead of typing 4 + 7 one would 
  620. type 4 7 + which would leave the value 11 on the top of the stack.  This 
  621. illustrates an important thing to remember about using Forth, anything 
  622. that is entered is interpreted as either a word in the dictionary (more on 
  623. that later) or a number to be pushed on the stack, so entering 4 7 + told 
  624. Forth to push a 4 on the stack followed by a 7 and the + word adds the top 
  625. two stack items.  To see the value stored on the top of the stack use the 
  626. . word.  Note that this is a destructive operation, it prints the value at 
  627. the top of the stack and removes it from the stack as well.  To see the 
  628. top stack value but NOT remove it you need to enter dup . to first 
  629. duplicate the top item and then print it.  By default, Forth only operates 
  630. on 16-bit integers but Pocket Forth supports real numbers as well.  Forth 
  631. will interpret a value as a real number ONLY if it contains a decimal 
  632. point!  It is therefore important to enter a decimal point for every 
  633. number that should be a real number and to NOT use one on numbers that 
  634. should be integers.
  635.     Forth supports the standard arithmetic operations: +, -, *, /  (integers) 
  636. and f+, f-, f*, f/ (real numbers).  Use f. to print the top of stack as a 
  637. real number.  fdup duplicates the real number at the top of the stack 
  638. while fswap will switch the top two real numbers on the stack.  These few 
  639. words will allow for using Forth as a simple calculator.  Forth does not 
  640. support higher mathematical functions.
  641.     Forth derives its extensibility from the way in which programs are 
  642. written.  As Forth interprets tokens from the input line (anything 
  643. surrounded by spaces is a token) it either pushes it on the stack as a 
  644. number or looks it up as a word in its dictionary.  A Forth program, 
  645. therefore, consists of adding definitions to the dictionary.  Definitions 
  646. are begin with the : word and end with a semi-colon.  Once defined, the 
  647. word can be used in subsequent definitions.  Parameters are passed via the 
  648. stack.  Forth does allow for the use of variables and constants, though 
  649. these are slower than the stack.  Use the word variable (or fvariable) 
  650. followed by the name for the variable to create one.  Use <value> constant 
  651. ( or fconstant) <name> do define a constant.  Examples:  typing fvariable 
  652. stddev will create room in the dictionary for a floating point variable 
  653. named stddev while typing 3.141592 fconstant PI will create a constant for 
  654. pi.  Constants are really special words that push the value on the stack 
  655. so that typing pi will cause the value to be pushed on the stack.  
  656. However,  entering the name of a variable will NOT place its value on the 
  657. stack, but rather, the address where the variable is stored will be placed 
  658. on the stack.  To get the value of a variable a two word combination must 
  659. be used:  stddev f@ will 'fetch' a floating point number stored at the 
  660. address that stddev places on the stack.  Similarly, the value of an 
  661. integer variable is found using @ instead of f@.  To store a value in a 
  662. variable, use ! or f! :  3 age ! or 1.414 sqr2 f!.
  663.     Forth uses several standard control structures:  if else then, do loop 
  664. (or +loop), begin until, begin while repeat.  The phrase 
  665.  
  666. count @ 100 < if ." Yes, there is room" cr 
  667.                      else ." No, there is no room." cr then 
  668.  
  669. will check whether the current value of count is less than 100 or not.  
  670. Forth supports <, >, = for comparing integer values.  Pocket Forth has a 
  671. single word for comparing floating point numbers, fcompare, which returns 
  672. a -1 if f1<f2, 0 is f1=f2, and +1 if f1>f2, where f1 and f2 are the top 
  673. two stack numbers (assumed to be floating point).  It is important to note 
  674. that unlike most other Forth words, fcompare does not remove the top two 
  675. floating point numbers.
  676.     The do loop is similar to the for loops in other languages.  As might be 
  677. expected, the syntax is  <hi> <lo> do <body> loop where the index (pushed 
  678. on the stack by the word r) will go from <lo> to <hi>-1.  A variation is 
  679. to use +loop instead of loop to jump by the value on the top of the stack 
  680. (which must be positive).  Begin until and begin while repeat are for 
  681. bottom tested and top tested conditional loops.  The condition is the same 
  682. as for the if statement:
  683.  
  684. 0 begin  ." Hello" cr 1+ dup 100 < until  
  685.  
  686. will print the word 'Hello' 100 times.  Similarly, this fragment will also 
  687. print 'Hello' 100 times:
  688.  
  689. 0 begin  dup 99 <  while  ." Hello" cr 1+  repeat
  690.  
  691.  
  692.    Putting it all together
  693.  
  694.     The following examples will illustrate the creation of simple Forth 
  695. words, after which an example using fractal generating words will be 
  696. presented.
  697.  
  698. 1.  Averaging four numbers
  699.  
  700.     :  ave4  ( a b c d -- average )  + + + 4 / ;
  701.  
  702. Using integer arithmetic, sum the top four stack items and divide the 
  703. result by 4.  Illustrates comments which are anything surrounded by (), 
  704. note the space after the (.  The comment given is known as a stack effect 
  705. comment and shows what effect the word has on the stack.  Initial stack 
  706. items are on the left of the -- and the result is on the right.
  707.  
  708. 2.  Averaging N floating point numbers
  709.  
  710.     :  averageN ( a1. ... aN. N -- average. )
  711.         dup >r     ( save N on the return stack )
  712.         1- 0 do     ( adjust N and add the values ) 
  713.                   f+ loop  
  714.         r>         ( get N off the return stack )
  715.         0 d>f f/ ;     ( make it real and divide to find average )
  716.  
  717. This example illustrates use of the return stack.  The return stack is the 
  718. place where Forth places addresses to return to when the current word is 
  719. done executing.  While a word is executing it is possible to use the 
  720. return stack for temporary storage, but one must be careful to make sure 
  721. that all values placed on the stack by >r are removed using r> before the 
  722. word is done, otherwise Forth will attempt to return to ??? and very 
  723. likely crash.  The way to convert an integer to a real number is to use 
  724. the words 0 d>f. This transforms the integer into a double length integer 
  725. and then into a real number.
  726.  
  727. 3.  Evaluating a function:  Y = 3.4 * EXP (X^2)
  728.  
  729.     fvariable x
  730.     : sqr  ( x. -- x.*x. )  fdup f* ;
  731.     : cube  ( x. -- x.^3  )  fdup fdup f* f* ;
  732.     : expf  ( x. -- exp[x.] )  ( use Taylor series approx. )
  733.        fdup x f! 1.0 f+ x f@ sqr 2.0 f/ f+ x f@ cube 6.0 f/ f+ ;
  734.     : Y  ( x. --  Y[x.] )  expf 3.4 f* ;
  735.        
  736. This is an example of factoring: the code for the square and cube could 
  737. easily have been left in the definition of expf but factoring them out 
  738. made the definition shorter and easier to read.  In theory, according to 
  739. some, a properly factored Forth program, combined with well chosen word 
  740. names and stack effect comment, should be nearly self-documenting.
  741.     These examples are brief, but hopefully should be sufficient, especially 
  742. when combined with a list of Forth words, to allow writing of simple words 
  743. to extend the power of the program.
  744.  
  745.  
  746.    The Sierpinski Triangle :  an example
  747.  
  748.  
  749.     The Sierpinski Triangle is a commonly seen fractal consisting of a 
  750. triangle that is made up of triangles.  This will serve as an example of 
  751. how the program can be extended by adding words to the Forth dictionary. 
  752. The triangle is made up of three maps that divide the region 0..1 in x and 
  753. 0..1 in y into three equal squares.  We will develop a Forth word that 
  754. will find the maps for the triangle and then generate the fractal. 
  755.     First, we must determine the maps.  The findmap command's interactive 
  756. nature is unsuited to our task, fortunately, there are three 'primitive' 
  757. (i.e. non-interactive) words that will perform the same task: initial, 
  758. image, and solve.  These words operate as follows:
  759.  
  760. <x1> <y1> <x2> <y2> <x3> <y3> initial
  761.     Sets the initial points for finding a map, (x1,y1),(x2,y2),(x3,y3).
  762.  
  763. <X1> <Y1> <X2> <Y2> <X3> <Y3> image
  764.     Sets the image points for finding a map, (X1,Y1),(X2,Y2),(X3,Y3).
  765.  
  766. solve
  767.     Finds the values that will map the initial points to the image points.
  768.  
  769. These words, when combined with make and set, will allow us to create a 
  770. single Forth word to find all three maps at once.  At this point, then, we 
  771. can write:
  772.  
  773. : sierpinski  ( generates the Sierpinski Triangle)
  774.     ( Set up initial values, for all maps )
  775.     0.0 0.0 1.0 0.0 0.0 1.0 initial
  776.     ( First map )
  777.     0.0 0.0 0.5 0.0 0.0 0.5 image  solve
  778.     make 0.333 1 set
  779.     ( Second map )
  780.     0.5 0.0 1.0 0.0 0.5 0.5 image  solve
  781.     make 0.333 2 set
  782.     ( Third map )
  783.     0.25 0.5 0.75 0.5 0.25 1.0 image  solve
  784.     make 0.333 3 set
  785.  
  786. Now before viewing the fractal show the maps, reset the program and show 
  787. the settings, and draw the outlines:
  788.  
  789.     ( Show the maps )
  790.     page ." The Sierpinski maps: " cr showmaps
  791.     reset  settings
  792.     key drop  ( wait for a key press )
  793.     ( Show outlines when drawing )
  794.     on outlines
  795.     ( Reset the program and draw the fractal )
  796.     cdraw  ;
  797.  
  798.  
  799. Try this word and see what happens.
  800.  
  801.   
  802.  
  803.  
  804.  
  805.  
  806.  Basic Forth words
  807.  
  808. Below is a list of some basic Forth words and their use.  With these it 
  809. should be possible to define your own words for use with the program.
  810.  
  811. Word                            Use
  812. swap    ( a b -- b a )        Switch top two stack items
  813. dup        ( a -- a a )        Duplicate top of stack
  814. over        ( a b -- a b a )        Bring 2nd to top
  815. rot        ( a b c -- b c a )    Rotate stack items
  816. variable    ( -- )            Make a variable of next token
  817. constant    ( a -- )            Make a constant of next token
  818. +, -, *, /    ( a b -- a$b )        Math, where $ is an operation
  819. mod        ( a b -- a mod b )    Remainder after dividing
  820. drop        ( a -- )            Drop the top stack item
  821. cr        ( -- )            Print a return character
  822. space    ( -- )            Print a space (ASCII 32)
  823. emit        ( a -- )            Print the character whose code
  824.                         is on the stack
  825. ."        ( -- )            Print text until a " found
  826. .        ( a -- )            Print the top of stack
  827. key        ( -- a )            Get a key, ASCII code on stack
  828. bye        ( -- )            Exit from Forth
  829. open        ( -- )            Load a file from disk
  830. ?terminal ( -- b )            Has a key been pressed?
  831. (        ( -- )            Start a comment (remember space)
  832. !pen        ( x y -- )            Move the pen to (x,y) (pixels)
  833. -to        ( x y -- )            Line from current to (x,y)
  834. page        ( -- )            Clear the screen
  835. -->            ( -- )            Load filename, no spaces!
  836. open        ( -- )            Load file chosen in Mac dialog
  837. ?button       ( -- t )            Mouse button down?
  838. @mouse      ( -- x y )            Push mouse position on stack
  839. save        ( -- )            Save the current dictionary.  This is PERMANANT!
  840.   Only use a copy!  Once saved, the words you defined will be available 
  841.   immediately when the program is next run.
  842.  
  843. See the reference section for more words that are program specific.  Words 
  844. in plain text are special to Pocket Forth and may not be available on 
  845. other Forth systems, though there will likely be something like them.
  846. Those interested in seriously learning Forth (some swear that it is the 
  847. best computer language there is) should get a hold of the book Starting 
  848. Forth by Leo Brodie (2nd ed. 1987), it is an excellent introduction.
  849.  
  850. Reference
  851.  
  852.  
  853.    Commands
  854.  
  855. draw
  856.     Draw a fractal based on the current maps.  Press a key to stop.
  857.     E.g.    green color fern draw
  858.  
  859. cdraw
  860.     Except for plotting each map in a different color, it is the same as
  861.     draw.
  862.     E.g.    spiral cdraw
  863.  
  864. <n> idraw or <n> icdraw
  865.     Same as draw and cdraw respectively except for iterating through
  866.     <n>*500 points.  Useful for drawing a fractal and stopping without
  867.     user interaction.
  868.  
  869. <n> edit
  870.     Edit the n-th map.  Enter a new value or press return to leave the
  871.     existing value as is.
  872.     E.g.    2 edit
  873.       a = 0.5        ?-0.5    (new value)
  874.       b = -0.5        ?<return>   etc.
  875.  
  876. zero-maps
  877.     Erase all twelve maps.
  878.     E.g.    zero-maps
  879.  
  880. <color.name> color
  881.     Set the current drawing color to the color named.  Valid colors are
  882.     black, wite, red, green, blue, yellow, cyan, magenta
  883.     E.g.    magenta color
  884.  
  885. <n> maps
  886.     Set the number of maps to use to <n>.
  887.     E.g.    4 maps
  888.  
  889.  
  890. <x> <y> origin
  891.     Set the origin to (x,y).  X and Y are floating point numbers.
  892.     E.g.    -0.354 .789 origin
  893.  
  894. <u> <v> screen
  895.     Set the screen origin to (u,v) (pixels).
  896.     E.g.    120 220 screen
  897.  
  898. <r> range
  899.     Set the range to <r> (floating point).  The viewing window is a
  900.     square with the lower left corner as the origin and side length
  901.     as range.
  902.     E.g.    0.5 range
  903.  
  904. <x> <y> scale
  905.     Set the x-axis and y-axis scales to the floating point values given.
  906.     The default scale is 1.0 for a full screen image.  Changing the scale
  907.     to a value less than one shrinks the image, greater than one expands
  908.     the image.
  909.     E.g.    2.0 2.0 scale
  910.  
  911. mouse
  912.     When issued, mouse will translate the position of the pointer into
  913.     an x,y coordinate allowing the user to 'see' where certain parts of 
  914.     the image are.  Clicking the mouse button between two points will
  915.     measure the distance between them.  Press a key to exit.
  916.  
  917. on|off clear
  918.     Turn clearing of page before drawing on and off. Default is on.
  919.  
  920. on|off axes
  921.     Turn the coordinate axes (really a mark on the origin) ON or OFF.
  922.     E.g.    off axes
  923.  
  924. on|off outlines
  925.     Set showing the map outlines on or off, press a key to continue
  926.     after viewing the outlines.
  927.     E.g.    on outlines
  928.  
  929.  
  930. settings
  931.     Show a list of the current origin, screen origin, range, scale, number
  932.     of maps and whether the axes and outlines are on or off.
  933.     E.g.    settings
  934.  
  935. findmap
  936.     Allows the user to enter three initial coordinates and three image
  937.     coordinates and calculates the map for those values.
  938.     E.g.    findmap
  939.  
  940. make
  941.     Puts the most recent values from findmap on the stack in order
  942.     for set.  The user needs to add the probability and map number
  943.     before calling set.
  944.     E.g.    make .333 1 set
  945.  
  946. <a> <b> <c> <d> <e> <f> <p> <n> set
  947.     Sets the parameters for a map.  The letters a-f correspond to the 
  948.     values for the matrix and offset vector, <p> is the probability for
  949.     the map and <n> is the map number.  All values except <n> are to
  950.     be floating point numbers.
  951.     E.g.    0.5 -0.5 0.5 0.5 0.0 0.0 0.5 1 set
  952.  
  953. <m1> <m2> copy
  954.     Copy map number <m1> to <m2> without disturbing <m1>.
  955.     E.g.    2 5 copy
  956.  
  957. <m> delete
  958.     Delete map number <m> and move any other maps up in memory.
  959.     E.g.    3 delete
  960.  
  961. <m> insert
  962.     Insert a blank map before map <m>.
  963.     E.g.    1 insert
  964.  
  965. cls
  966.     Clear the window.
  967.     E.g.    cls
  968.  
  969.  
  970. bye
  971.     Exit Fractal Lab Kit.
  972.     E.g.    bye
  973.  
  974.  
  975. <9|12|13> monitor
  976.     Set the program for a 9, 12, or 13 inch monitor.
  977.     E.g.    13 monitor
  978.  
  979. mem
  980.     Show the available dictionary space.  (Forth only has 32k)
  981.     E.g.    mem
  982.  
  983. ?origin, ?screen, ?scale, ?range, ?maps, ?axes, ?outline, ?clear
  984.     Show individual settings.  settings calls each of these.
  985.  
  986. <n> show
  987.     Show the values of map <n>.
  988.     E.g.    3 show
  989.  
  990.  
  991.  
  992.    Primitive commands
  993.  
  994. These commands (words) are 'primitive' in the sense that they are called 
  995. by the regular command words.  Since they are standard Forth words they 
  996. are available for user use as well.
  997.  
  998.  
  999. input   ( -- a )
  1000.     Get a 16-bit integer on the stack.
  1001.  
  1002. finput  ( -- f b )
  1003.     Get a floating point number on the stack and a boolean value that is
  1004.     true if the user pressed the return key only, in which case the 
  1005.     number is 0.0.
  1006.  
  1007. #map->addr  ( a -- addr )
  1008.     Convert a number for a map into an address to the map location in
  1009.     memory.
  1010.  
  1011. get   ( offset map# -- value )
  1012.     Get a value for a particular map.  The offset is a branch into the
  1013.     map, each value is 10 bytes long.  The constants a,b,c,d,e,f and p
  1014.     are defined to give the proper offset:  c 3 get  returns the c value
  1015.     of the third map.
  1016.  
  1017. update  ( value offset map# -- )
  1018.     Put the value in the numbered map at the offset (use  a-f or p).
  1019.  
  1020. print  ( addr -- )
  1021.     Print the map starting at addr.
  1022.  
  1023. wsize   ( h v -- )
  1024.     Resize the window to h pixels high and v pixels across.
  1025.  
  1026. rand   ( -- f )
  1027.     Put a random floating point number from 0..1 on the stack.
  1028.  
  1029. dot   ( u v -- )
  1030.     Draw a dot on the screen at (u,v) (pixels).
  1031.  
  1032. plot   ( x. y. -- )
  1033.     Plot the point (x,y) on the screen.
  1034.  
  1035. plotto   ( x. y. -- )
  1036.     Draw a line from the last plotted point to (x,y).
  1037.  
  1038. determinant  ( -- d )
  1039.     Find the determinant of the 3x3 matrix whose values are stored
  1040.     in the floating point variables d1 through d9.  Values in the form:
  1041.     [ [d1,d2,d3],[d4,d5,d6].[d7,d8,d9]].
  1042.  
  1043. x->d  ( -- )
  1044.     Copy the values in x1,y1 .. x3,y3 to the matrix d.  Used to setup for
  1045.     finding a map.
  1046.  
  1047. xy->uv  ( x. y. -- u v )
  1048.     Change real coordinates (x,y) into screen coordinates (u,v).  Call
  1049.     factor first.
  1050.  
  1051. factor  ( -- )
  1052.     Calculates redundant factors for xy->uv to speed drawing.
  1053.  
  1054. firstpoints  ( -- )
  1055.     Get the initial points for a map, interactive.
  1056.  
  1057. solve3x3  ( -- f. d. c. e. b. a. )
  1058.     Solve for a map, calculated values on stack.  Call either firstpoints
  1059.     and imagepoints or initial and image before calling solve3x3.
  1060.  
  1061. outputmap  ( f. d. c. e. b. a. -- )
  1062.     Display map values on the stack on the screen.
  1063.